﻿//using System.Threading;
//using VIA.Integration;
//using VIA.Integration.Alarms;
//using VNetDxf.Entities;

//namespace VIA.SiMoJi.Domain.Electronics
//{
//    public class DmcAxis : Axis, IHasOption<AxisOption>
//    {
//        private volatile ushort usDir = 0;
//        private bool _isMoveTimeoutError;
//        private bool _isStatusError;
//        private bool _isHomeError;
//        public ushort CardId => Electronic.CardId;
//        /// <summary>
//        /// 轴在轴卡上的编号
//        /// </summary>
//        public ushort NoId { get; private set; }
//        public override double Current { get => GetCurrentPosition(); }
//        public override bool IsDone { get => CheckIsDone(); }
//        public bool IsServoOn { get => CheckIsServoOn(); }
//        public short ReturnState { get; private set; }

//        [Alarm(true, AlarmLevel.Error, Description = "轴移动超时")]
//        public bool IsMoveTimeoutError { get => _isMoveTimeoutError; set => this.NotifyAlarm(ref _isMoveTimeoutError, value); }
//        [Alarm(true, AlarmLevel.Error, Description = "轴状态报警")]
//        public bool IsStatusError { get => _isStatusError; set => this.NotifyAlarm(ref _isStatusError, value); }
//        [Alarm(true, AlarmLevel.Error, Description = "轴回原点失败")]
//        public bool IsHomeError { get => _isHomeError; set => this.NotifyAlarm(ref _isHomeError, value); }

//        /// <summary>
//        /// 轴参数
//        /// </summary>
//        public AxisOption Option { get; set; } = new();
//        public DmcAxis(ushort id)
//        {
//            this.InitalizeAlarms();
//            NoId = id; Option.UsAxis = id;
//        }

//        /// <summary>
//        /// 移动到点位并且查询是否完成
//        /// </summary>
//        /// <param name="value"></param>
//        /// <param name="speed"></param>
//        /// <param name="cancelToken"></param>
//        /// <param name="timeout"></param>
//        /// <param name="isCheckPosition"></param>
//        /// <param name="interval"></param>
//        /// <returns></returns>
//        public async Task<bool> MoveToPositionAsync(double value, double speed, CancellationToken cancelToken = default, int timeout = 20_000, bool isCheckPosition = true, int interval = 100)
//        {
//            ReturnState = LTDMC.dmc_set_profile_unit(CardId, NoId, Option.StartVel, speed, Option.AccTime, Option.DecTime, Option.StopVel);//设置速度参数
//            ReturnState = LTDMC.dmc_set_s_profile(CardId, NoId, 0, Option.SparaTime);                                    //设置S段速度参数
//            ReturnState = LTDMC.dmc_pmove_unit(CardId, NoId, value, 1);
//            if (!await Judger.Sure(CheckIsDone, cancelToken, timeout, interval))
//            {
//                IsMoveTimeoutError = true;
//                return false;
//            }
//            if (isCheckPosition)
//            {
//                if (!CheckIsInPosition(value))
//                {
//                    IsMoveTimeoutError = true;
//                    return false;
//                }
//            }
//            return true;
//        }

//        /// <summary>
//        /// 移动到点位并且查询是否完成
//        /// </summary>
//        /// <param name="value"></param>
//        /// <param name="speed"></param>
//        /// <param name="cancelToken"></param>
//        /// <param name="timeout"></param>
//        /// <param name="isCheckPosition"></param>
//        /// <param name="interval"></param>
//        /// <returns></returns>
//        public async Task<bool> MoveToPositionAsync(string paramName, CancellationToken cancelToken = default, int timeout = 20_000, bool isCheckPosition = true, int interval = 100)
//        {
//            var param = GetAxisPointParam(paramName);
//            return await MoveToPositionAsync(param.Position, param.Speed, cancelToken, timeout, isCheckPosition, interval);
//        }

//        /// <summary>
//        /// 移动到点位并且查询是否完成
//        /// </summary>
//        /// <param name="value"></param>
//        /// <param name="speed"></param>
//        /// <param name="cancelToken"></param>
//        /// <param name="timeout"></param>
//        /// <param name="isCheckPosition"></param>
//        /// <param name="interval"></param>
//        /// <returns></returns>
//        public async Task<bool> MoveToPositionAsync(AxisPointParam param, CancellationToken cancelToken = default, int timeout = 20_000, bool isCheckPosition = true, int interval = 100)
//        {
//            return await MoveToPositionAsync(param.Position, param.Speed, cancelToken, timeout, isCheckPosition, interval);
//        }

//        /// <summary>
//        /// 移动定长并且查询是否完成
//        /// </summary>
//        /// <param name="value"></param>
//        /// <param name="speed"></param>
//        /// <param name="cancelToken"></param>
//        /// <param name="timeout"></param>
//        /// <param name="isCheckPosition"></param>
//        /// <param name="interval"></param>
//        /// <returns></returns>
//        public async Task<bool> MoveDeltaAsync(double value, double speed, CancellationToken cancelToken = default, int timeout = 20_000, bool isCheckPosition = true, int interval = 100)
//        {
//            ReturnState = LTDMC.dmc_set_profile_unit(CardId, NoId, Option.StartVel, speed, Option.AccTime, Option.DecTime, Option.StopVel);//设置速度参数
//            ReturnState = LTDMC.dmc_set_s_profile(CardId, NoId, 0, Option.SparaTime);                                    //设置S段速度参数
//            ReturnState = LTDMC.dmc_pmove_unit(CardId, NoId, value, 0);
//            if (!await Judger.Sure(CheckIsDone, cancelToken, timeout, interval))
//            {
//                return false;
//            }
//            if (isCheckPosition)
//            {
//                return CheckIsInPosition(value);
//            }
//            return true;
//        }
//        public async Task<bool> MoveDeltaAsync(string paramName, CancellationToken cancelToken = default, int timeout = 20_000, bool isCheckPosition = true, int interval = 100)
//        {
//            var param = GetAxisPointParam(paramName);
//            return await MoveDeltaAsync(param.Position, param.Speed, cancelToken, timeout, isCheckPosition, interval);
//        }

//        public async Task<bool> MoveDeltaAsync(double value, CancellationToken cancelToken = default, int timeout = 20_000, bool isCheckPosition = true, int interval = 100)
//        {
//            return await MoveDeltaAsync(value, Option.MaxVel, cancelToken, timeout, isCheckPosition, interval);
//        }

//        public Task PostiveAsync(double speed, CancellationToken cancelToken = default)
//        {
//            ReturnState = LTDMC.dmc_set_profile_unit(CardId, NoId, Option.StartVel, speed, Option.AccTime, Option.DecTime, Option.StopVel);
//            ReturnState = LTDMC.dmc_set_s_profile(CardId, NoId, 0, Option.SparaTime);
//            usDir = Option.FlipMoveDirection ? (ushort)0 : (ushort)1;
//            ReturnState = LTDMC.dmc_vmove(CardId, NoId, usDir);
//            return Task.CompletedTask;
//        }

//        public Task PostiveAsync(string name, CancellationToken cancelToken = default)
//        {
//            double sp = GetAxisPointParam(name).Speed;
//            return PostiveAsync(sp, cancelToken);
//        }

//        public Task NegativeAsync(double speed, CancellationToken cancelToken = default)
//        {
//            ReturnState = LTDMC.dmc_set_profile_unit(CardId, NoId, Option.StartVel, speed, Option.AccTime, Option.DecTime, Option.StopVel);//设置速度参数
//            ReturnState = LTDMC.dmc_set_s_profile(CardId, NoId, 0, Option.SparaTime);
//            usDir = Option.FlipMoveDirection ? (ushort)1 : (ushort)0;
//            ReturnState = LTDMC.dmc_vmove(CardId, NoId, usDir);
//            return Task.CompletedTask;
//        }

//        public Task NegativeAsync(string name, CancellationToken cancelToken = default)
//        {
//            double sp = GetAxisPointParam(name).Speed;
//            return NegativeAsync(sp, cancelToken);
//        }

//        public override Task MoveDeltaAsync(double value, VelocityCurve velocityCurve = null, CancellationToken cancelToken = default)
//        {
//            ReturnState = LTDMC.dmc_set_profile_unit(CardId, NoId, Option.StartVel, Option.MaxVel, Option.AccTime, Option.DecTime, Option.StopVel);//设置速度参数
//            ReturnState = LTDMC.dmc_set_s_profile(CardId, NoId, 0, Option.SparaTime);                                    //设置S段速度参数
//            ReturnState = LTDMC.dmc_pmove_unit(CardId, NoId, value, 0);
//            return Task.CompletedTask;
//        }

//        public override async Task MoveToAsync(double value, VelocityCurve velocityCurve = null, CancellationToken cancelToken = default)
//        {
//            var speed = velocityCurve?.Maxvel ?? Speed;
//            ReturnState = LTDMC.dmc_set_profile_unit(CardId, NoId, Option.StartVel, speed, Option.AccTime, Option.DecTime, Option.StopVel);//设置速度参数
//            ReturnState = LTDMC.dmc_set_s_profile(CardId, NoId, 0, Option.SparaTime);                                    //设置S段速度参数
//            ReturnState = LTDMC.dmc_pmove_unit(CardId, NoId, value, 1);
//            if (!await Judger.Sure(CheckIsDone, cancelToken, timeout, interval))
//            {
//                IsMoveTimeoutError = true;
//                return;
//            }
//            if (isCheckPosition)
//            {
//                if (!CheckIsInPosition(value))
//                {
//                    IsMoveTimeoutError = true;
//                }
//            }
//        }

//        public override async Task PostiveAsync(VelocityCurve velocityCurve = null, CancellationToken cancelToken = default)
//        {
//            await PostiveAsync(Option.MaxVel,cancelToken);
//        }

//        public override async Task NegativeAsync(VelocityCurve velocityCurve = null, CancellationToken cancelToken = default)
//        {
//            await NegativeAsync(Option.MaxVel, cancelToken);
//        }

//        public override Task PauseAsync(VelocityCurve velocityCurve = null, CancellationToken cancelToken = default)
//        {
//            ReturnState = LTDMC.dmc_set_dec_stop_time(CardId, NoId, Option.DecTime);  //设置减速停止时间
//            ReturnState = LTDMC.dmc_stop(CardId, NoId, 0); //usStopMode:制动方式，0：减速停止，1：紧急停止
//            return Task.CompletedTask;
//        }

//        public void Stop()
//        {
//            ReturnState = LTDMC.dmc_set_dec_stop_time(CardId, NoId, Option.DecTime);  //设置减速停止时间
//            ReturnState = LTDMC.dmc_stop(CardId, NoId, 0); //usStopMode:制动方式，0：减速停止，1：紧急停止
//        }

//        public override Task ResumeAsync(CancellationToken cancelToken = default)
//        {
//            return Task.Run(() =>
//            {
//                ReturnState = LTDMC.dmc_vmove(CardId, NoId, usDir);
//            }, cancelToken);
//        }

//        /// <summary>
//        /// 获取轴点位参数
//        /// </summary>
//        /// <param name="name"></param>
//        /// <returns></returns>
//        /// <exception cref="Exception"></exception>
//        public AxisPointParam GetAxisPointParam(string name)
//        {
//            var ps = Option.AxisPositions.FirstOrDefault(x => x.Name == name);
//            if (ps == null)
//            {
//                throw new Exception($"{Name}轴中没有找到名为{name}的点位!");
//            }
//            return ps;
//        }

//        /// <summary>
//        /// 添加轴点位参数
//        /// </summary>
//        /// <param name="name"></param>
//        /// <returns>true-成功添加点位,false-已经存在点位</returns>
//        public bool AddAxisPointParam(string name)
//        {
//            var ps = Option.AxisPositions.FirstOrDefault(x => x.Name == name);
//            if (ps == null)
//            {
//                ps = new AxisPointParam(name, 0, 0);
//                Option.AxisPositions.Add(ps);
//                return true;
//            }
//            return false;
//        }

//        /// <summary>
//        /// 异步回零操作
//        /// </summary>
//        /// <param name="timeOut"></param>
//        /// <param name="interval"></param>
//        /// <param name="cancelToken"></param>
//        /// <returns></returns>
//        public async Task<bool> HomeAsync(CancellationToken cancelToken = default, int timeOut = 30_000, int interval = 200)
//        {
//            ReturnState = LTDMC.nmc_set_home_profile(CardId, NoId, Option.HomeMode, Option.HomeLowSpeed, Option.HomeHighSpeed, Option.HomeAccTime, Option.HomeDecTime, Option.HomeOffset);
//            ReturnState = LTDMC.nmc_home_move(CardId, NoId);//启动回零 
//            ushort state = 0;
//            bool isDone = await WaitDoneAsync(cancelToken, timeOut, interval);
//            if (!isDone) return false;
//            LTDMC.dmc_get_home_result(CardId, NoId, ref state);//判断回零是否正常完成。
//            if (state != 1) return false;
//            if(!Option.NoneORG)
//            {
//                uint unIoState = LTDMC.dmc_axis_io_status(CardId, NoId);
//                bool b = (unIoState & 16) == 16;//检测原点信号是否亮
//                if (!b)
//                {
//                    IsHomeError = true;
//                }
//                LTDMC.dmc_set_position_unit(CardId, NoId, 0);
//                return b;
//            }
//            return true;
//        }

//        /// <summary>
//        /// 急停
//        /// </summary>
//        /// <param name="velocityCurve"></param>
//        /// <param name="cancelToken"></param>
//        /// <returns></returns>
//        public void ForceStopAsync()
//        {
//            ReturnState = LTDMC.dmc_stop(CardId, NoId, 1); //usStopMode:制动方式，0：减速停止，1：紧急停止
//        }

//        /// <summary>
//        /// 等待轴运动完成
//        /// </summary>
//        /// <param name="timeOut"></param>
//        /// <param name="interval"></param>
//        /// <param name="cancelToken"></param>
//        /// <returns></returns>
//        public Task<bool> WaitDoneAsync(CancellationToken cancelToken = default, int timeOut = 10_000, int interval = 50)
//        {
//            return Judger.Sure(CheckIsDone, cancelToken, timeOut, interval);
//        }

//        /// <summary>
//        /// 检测状态
//        /// </summary>
//        /// <returns></returns>
//        public bool CheckIsServoOn()
//        {
//            ushort state = 0;
//            ReturnState = LTDMC.nmc_get_axis_state_machine(CardId, NoId, ref state);
//            bool b = state == 4;
//            return b;
//        }

//        /// <summary>
//        /// 检测轴是否运动完成，true：指定轴已运动完成，处于停止状态，false：指定轴未运动完成，处于运行状态
//        /// </summary>
//        /// <returns></returns>
//        public bool CheckIsDone()
//        {
//            ReturnState = LTDMC.dmc_check_done(CardId, NoId);
//            return ReturnState == 1;
//        }

//        /// <summary>
//        /// 检测轴编码器是否在误差范围内
//        /// </summary>
//        /// <returns></returns>
//        public bool CheckEncoderSuccess()
//        {
//            ReturnState = LTDMC.dmc_set_factor_error(CardId, NoId, Option.EncoderFactor, Option.ErrorTolerance);
//            ReturnState = LTDMC.dmc_check_success_encoder(CardId, NoId);
//            return ReturnState == 0;
//        }

//        /// <summary>
//        /// 检测轴是否在指定位置
//        /// </summary>
//        /// <param name="position">指定位置</param>
//        /// <param name="tolerance">误差允许</param>
//        /// <returns></returns>
//        public bool CheckIsInPosition(double position, double tolerance = 0.5)
//        {
//            var ps = GetCurrentPosition();
//            return Math.Abs(ps - position) < tolerance;
//        }

//        /// <summary>
//        /// 检测轴是否在指定名称所在位置
//        /// </summary>
//        /// <param name="position">轴位置名称</param>
//        /// <param name="tolerance">误差允许</param>
//        /// <returns></returns>
//        public bool CheckIsInPosition(string position, double tolerance = 0.5)
//        {
//            var dest = GetAxisPointParam(position).Position;
//            var ps = GetCurrentPosition();
//            return Math.Abs(ps - dest) < tolerance;
//        }

//        /// <summary>
//        /// 检测轴是否在预设定的位置之一
//        /// </summary>
//        /// <param name="position">预设定位置名称</param>
//        /// <returns></returns>
//        public bool CheckIsInModelPosition(out string position)
//        {
//            foreach (var item in Option.AxisPositions)
//            {
//                if (CheckIsInPosition(item.Name))
//                {
//                    position = item.Name;
//                    return true;
//                }
//            }
//            position = string.Empty;
//            return false;
//        }

//        /// <summary>
//        /// 设置使能On
//        /// </summary>
//        /// <returns></returns>
//        public virtual short SetEnableOn()
//        {
//            ReturnState = LTDMC.nmc_set_axis_enable(CardId, NoId);
//            return ReturnState;
//        }

//        /// <summary>
//        /// 设置使能Off
//        /// </summary>
//        /// <returns></returns>
//        public virtual short SetEnableOff()
//        {
//            ReturnState = LTDMC.nmc_set_axis_disable(CardId, NoId);
//            return ReturnState;
//        }

//        /// <summary>
//        /// 设置轴的参数
//        /// </summary>
//        public short SetParam()
//        {
//            ReturnState = LTDMC.dmc_set_profile_unit(CardId, NoId, Option.StartVel, Option.MaxVel, Option.AccTime, Option.DecTime, Option.StopVel);//设置速度参数
//            ReturnState = LTDMC.dmc_set_s_profile(CardId, NoId, 0, Option.SparaTime);                                    //设置S段速度参数
//            ReturnState = LTDMC.dmc_set_equiv(CardId, NoId, Option.PulseEquivalent);//设置脉冲当量
//            ReturnState = LTDMC.dmc_set_equiv(CardId, NoId, Option.PulseEquivalent);//设置脉冲当量
//            ReturnState = SetSoftLimit(Option.NagetiveLimit, Option.PositiveLimit);
//            ReturnState = LTDMC.nmc_set_home_profile(CardId, NoId, Option.HomeMode, Option.HomeLowSpeed, Option.HomeHighSpeed, Option.HomeAccTime, Option.HomeDecTime, Option.HomeOffset);
//            return ReturnState;
//        }

//        /// <summary>
//        /// 在线改变指定轴的当前运动速度
//        /// </summary>
//        /// <param name="speed">新的速度</param>
//        /// <param name="reversal">是否反转方向</param>
//        /// <returns></returns>
//        public short ChangeSpeed(double speed, bool reversal = false)
//        {
//            if (reversal) speed = -speed;
//            ReturnState = LTDMC.dmc_change_speed_unit(CardId, NoId, speed, 0);
//            return ReturnState;
//        }

//        /// <summary>
//        /// 设置为原点，指令位置和编码器位置同时清0：不允许单独设置指令位置为0或者单独设置编码器位置为0
//        /// </summary>
//        public void SetOriginal()
//        {
//            ReturnState = LTDMC.dmc_set_position_unit(CardId, NoId, 0);
//        }

//        /// <summary>
//        /// 设置软限位位置，根据脉冲当量换算为mm
//        /// </summary>
//        /// <param name="nLimit">负限位mm</param>
//        /// <param name="pLimit">正限位mm</param>
//        /// <param name="source_sel">计数器选择，0：指令位置计数器，1：编码器计数器</param>
//        /// <param name="SL_action">限位停止方式，0：立即停止 1：减速停止</param>
//        public short SetSoftLimit(double nLimit, double pLimit, ushort source_sel = 1, ushort SL_action = 1)
//        {
//            ushort enable = Option.IsIgnoreLimit ? (ushort)0 : (ushort)1;
//            return ReturnState = LTDMC.dmc_set_softlimit_unit(CardId, NoId, enable, source_sel, SL_action, nLimit, pLimit);
//        }

//        /// <summary>
//        /// 设置一维高速队列比较器
//        /// </summary>
//        /// <param name="compareId">比较器号</param>
//        /// <param name="comparePostions">比较点，单位mm</param>
//        /// <param name="usCmpSource">1-比较源为辅助编码器位置</param>
//        /// <param name="usCmpLogic">有效电平，0-低电平，1-高电平</param>
//        /// <param name="nTime">输出脉冲宽度，单位：us，取值范围：1us~20s</param>
//        public void SetupTriggerTable(ushort compareId, List<double> comparePostions, ushort usCmpSource = 1, ushort usCmpLogic = 1, int nTime = 1000)
//        {
//            LTDMC.dmc_hcmp_set_config(CardId, compareId, NoId, usCmpSource, usCmpLogic, nTime);//配置比较器0关联轴0，比较源为辅助编码器计数器
//            LTDMC.dmc_hcmp_clear_points(CardId, compareId);//清除比较点
//            LTDMC.dmc_hcmp_set_mode(CardId, compareId, 4);//设置高速比较模式为队列模式
//            foreach (var item in comparePostions)
//            {
//                LTDMC.dmc_hcmp_add_point_unit(CardId, compareId, item);
//            }
//        }

//        /// <summary>
//        /// 设置一维高速线性比较器
//        /// </summary>
//        /// <param name="compareId">比较器号</param>
//        /// <param name="comparePostion">比较起始点，单位mm</param>
//        /// <param name="increment">设置高速比较线性模式参数，位置增量值</param>
//        /// <param name="count">设置高速比较线性模式参数，比较次数</param>
//        /// <param name="usCmpSource">1-比较源为辅助编码器位置</param>
//        /// <param name="usCmpLogic">有效电平，0-低电平，1-高电平</param>
//        /// <param name="nTime">输出脉冲宽度，单位：us，取值范围：1us~20s</param>
//        private void SetIncrementCompareConfig(ushort compareId, double comparePostion, double increment, int count, ushort usCmpSource = 1, ushort usCmpLogic = 1, int nTime = 1000)
//        {
//            LTDMC.dmc_hcmp_set_config(CardId, compareId, NoId, usCmpSource, usCmpLogic, nTime);//配置比较源为辅助编码器计数器
//            LTDMC.dmc_hcmp_clear_points(CardId, compareId);//清除比较点
//            LTDMC.dmc_hcmp_set_mode(CardId, compareId, 5);//设置高速比较模式为线性模式
//            LTDMC.dmc_hcmp_set_liner_unit(CardId, compareId, increment, count);//设置线性比较参数  
//            LTDMC.dmc_hcmp_add_point_unit(CardId, compareId, comparePostion);//添加比较点位置
//        }

//        /// <summary>
//        /// 获取当前位置,根据脉冲当量换算为mm
//        /// </summary>
//        /// <returns></returns>
//        public double GetCurrentPosition()
//        {
//            double pos = double.NaN;
//            ReturnState = LTDMC.dmc_get_position_unit(CardId, NoId, ref pos);
//            return pos;
//        }

//        /// <summary>
//        /// 获取轴参数
//        /// </summary>
//        /// <returns></returns>
//        public short GetParam()
//        {
//            double startVel = 1, maxVel = 1, accTime = 0.1, decTime = 0.1, stopVel = 0, sparaTime = 0, pulseEquivalent = 1;
//            ReturnState = LTDMC.dmc_get_profile_unit(CardId, NoId, ref startVel, ref maxVel, ref accTime, ref decTime, ref stopVel);
//            ReturnState = LTDMC.dmc_get_s_profile(CardId, NoId, 0, ref sparaTime);                                 
//            ReturnState = LTDMC.dmc_get_equiv(CardId, NoId, ref pulseEquivalent);
//            Option.StartVel = startVel;
//            Option.MaxVel = maxVel;
//            Option.AccTime = accTime;
//            Option.DecTime = decTime;
//            Option.StopVel = stopVel;
//            Option.SparaTime = sparaTime;
//            Option.PulseEquivalent = pulseEquivalent;

//            double nLimit = 0, pLimit = 0;
//            ushort enable = 0, source_sel = 0, SL_action = 0;
//            ReturnState = GetSoftLimit(ref nLimit, ref pLimit, ref enable, ref source_sel, ref SL_action);
//            Option.NagetiveLimit = nLimit;
//            Option.PositiveLimit = pLimit;

//            ushort homeMode = 0;
//            double homeHighSpeed = 0, homeLowSpeed = 0, homeTacc = 0, homeDecc = 0, offsetSteps = 0;
//            ReturnState = LTDMC.nmc_get_home_profile(CardId, NoId, ref homeMode, ref homeLowSpeed, ref homeHighSpeed, ref homeTacc, ref homeDecc, ref offsetSteps);
//            Option.HomeAccTime = homeTacc;
//            Option.HomeDecTime = homeDecc;
//            Option.HomeLowSpeed = homeLowSpeed;
//            Option.HomeHighSpeed = homeHighSpeed;
//            Option.HomeMode = homeMode;
//            Option.HomeOffset = offsetSteps;
//            return ReturnState;
//        }

//        /// <summary>
//        /// 获取当前速度,根据脉冲当量换算为mm/s
//        /// </summary>
//        /// <returns></returns>
//        public double GetSpeed()
//        {
//            double sp = double.NaN;
//            ReturnState = LTDMC.dmc_read_current_speed_unit(CardId, NoId, ref sp);
//            return sp;
//        }

//        /// <summary>
//        /// 获取当前软限位值，根据脉冲当量换算为mm
//        /// </summary>
//        /// <param name="nLimit">返回负限位mm</param>
//        /// <param name="pLimit">返回正限位mm</param>
//        /// <param name="enable">返回使能状态0：禁止，1：允许</param>
//        /// <param name="source_sel">返回计数器选择，0：指令位置计数器，1：编码器计数器</param>
//        /// <param name="SL_action">返回限位停止方式，0：立即停止 1：减速停止</param>
//        public short GetSoftLimit(ref double nLimit, ref double pLimit, ref ushort enable, ref ushort source_sel, ref ushort SL_action)
//        {
//            return ReturnState = LTDMC.dmc_get_softlimit_unit(CardId, NoId, ref enable, ref source_sel, ref SL_action, ref nLimit, ref pLimit);
//        }

//        /// <summary>
//        /// 获取轴停止原因
//        /// </summary>
//        /// <returns></returns>
//        public int GetStopReason(out string reason)
//        {
//            int data = 0;
//            ReturnState = LTDMC.dmc_get_stop_reason(CardId, NoId, ref data);
//            reason = GetReasonDesc(data);
//            return data;

//            string GetReasonDesc(int data)
//            {
//                switch (data)
//                {
//                    case 0:
//                        return "正常停止";
//                    case 1:
//                        return "ALM 立即停止";
//                    case 2:
//                        return "ALM 减速停止";
//                    case 3:
//                        return "LTC 外部触发立即停止";
//                    case 4:
//                        return "EMG 立即停止";
//                    case 5:
//                        return "正硬限位立即停止";
//                    case 6:
//                        return "负硬限位立即停止";
//                    case 7:
//                        return "正硬限位减速停止";
//                    case 8:
//                        return "负硬限位减速停止";
//                    case 9:
//                        return "正软限位立即停止";
//                    case 10:
//                        return "负软限位立即停止";
//                    case 11:
//                        return "正软限位减速停止";
//                    case 12:
//                        return "负软限位减速停止";
//                    case 13:
//                        return "命令立即停止";
//                    case 14:
//                        return "命令减速停止";
//                    case 15:
//                        return "其它轴引起的立即停止";
//                    case 16:
//                        return "其它轴引起的减速停止";
//                    case 17:
//                        return "模拟量超限，触发急停";
//                    case 18:
//                        return "保留";
//                    case 19:
//                        return "DSTP 信号引起的减速停止";
//                    case 20:
//                        return "前瞻预处理和速度规划来不及，底层自动调用 stoplist";
//                    case 21:
//                        return "原点不在两个限位之间停止";
//                    case 22:
//                        return "回零方向和当前有效限位端相反（正限位有效时，回零方向为负方向；负限位有效时，回零方向为正方向）";
//                    case 23:
//                        return "正负限位同时有效";
//                    case 24:
//                        return "没有找到 EZ 信号";
//                    case 25:
//                        return "回零位置溢出停止";
//                    case 26:
//                        return "动加速度过大，异常停止";
//                    case 27:
//                        return "双原点停止";
//                    case 28:
//                        return "区域限位立即停止";
//                    case 29:
//                        return "区域限位减速停止";
//                    case 30:
//                        return "龙门超差保护减速停止";
//                    case 31:
//                        return "龙门超差保护立即停止";
//                    case 32:
//                        return "插补规划错误停止";
//                    case 33:
//                        return "单轴跟踪误差保护立即停止";
//                    case 34:
//                        return "单轴跟踪误差保护减速停止";
//                    case 35:
//                        return "插补缓冲区错误停止";
//                    case 36:
//                        return "龙门主从轴超差保护立即停止";
//                    case 37:
//                        return "龙门主从轴超差保护减速停止";
//                    case 38:
//                        return "轴输出脉冲频率超过 4M";
//                    case 39:
//                        return "IO 触发立即停止";
//                    case 40:
//                        return "IO 触发减速停止";
//                    case 49:
//                        return "看门狗超时";
//                    case 50:
//                        return "两轴碰撞检测立即停止";
//                    case 51:
//                        return "两轴碰撞检测减速停止";
//                    case 52:
//                        return "龙门从轴 alm 引起主轴立即停止";
//                    case 53:
//                        return "从轴开始启动时主轴绝对位置错误（不在主轴运动方向上）";
//                    case 54:
//                        return "同步时主轴绝对位置错误（不在主轴运动方向上）";
//                    case 55:
//                        return "从轴开始运动位置大于同步时主轴绝对位置错误";
//                    case 56:
//                        return "同步时从轴绝对位置（不在从轴运动方向上）";
//                    case 57:
//                        return "不支持主轴运动模式（仅支持跟随主轴做定长和定速运动模式）";
//                    case 58:
//                        return "从轴追赶目标速度小于同步时从轴的速度";
//                    case 59:
//                        return "从轴同步位置过小，不足以从轴从当前速度直接加速或减速至同步速度";
//                    case 60:
//                        return "初始化时主轴运动方向错误(运动速度为零)";
//                    case 61:
//                        return "从轴开始运动时主轴未达到匀速状态";
//                    case 62:
//                        return "GearInPos 实际加速度大于设置的最大加速度";
//                    case 63:
//                        return "GearInPos 实际减速度大于设置的最大减速度";
//                    case 64:
//                        return "从轴追赶实际可达速度大于追赶设置的最大目标速度";
//                    case 65:
//                        return "从轴同步速度在只有加速或减速过程也不可达速度";
//                    case 66:
//                        return "二分法求取合适的可达速度，迭代次数超过限制次数让无法找到合适的速度值";
//                    case 67:
//                        return "主轴 pmove 目标位置小于主轴同步位置";
//                    case 68:
//                        return "主轴 pmove 目标位置小于从轴开始运动时的主轴位置";
//                    case 69:
//                        return "从轴追赶过程加速周期或减速周期为 0，有可能主轴同步位置和从轴开始运动时的主轴位置相隔太近";
//                    case 70:
//                        return "主轴目标速度为零";
//                    case 71:
//                        return "从轴实际可达速度大于追赶速度时，重算以追赶速度为目标速度的匀速周期数小于等于零";
//                    case 72:
//                        return "GearInPos 主轴位移与规划结果不一致";
//                    case 73:
//                        return "GearInPos 主轴 vmove 减速阶段不支持";
//                    case 74:
//                        return "从轴起始反向运动方向模式错误(1~4)";
//                    case 75:
//                        return "从轴起始反向运动加速度为零";
//                    case 76:
//                        return "连续轨迹等待外部 io 输入信号有效超时，停止插补系运动";
//                    case 201:
//                        return "正负限位之间全程没找到原点信号";
//                    case 202:
//                        return "回零方向不匹配";
//                    case 203:
//                        return "正负限位同时有效";
//                    case 204:
//                        return "正负限位之间全程没有 EZ 信号";
//                    case 205:
//                        return "位置溢出";
//                    case 206:
//                        return "双原点错误";
//                    case 207:
//                        return "外部信号触发回零停止";
//                    case 208:
//                        return "驱动器回零被中断停止";
//                    default:
//                        return "未知停止代码";
//                }
//            }
//        }

//        /// <summary>
//        /// 获取轴有关运动信号的状态,1-ON,0-OFF
//        /// 0位:表示伺服报警信号 ALM
//        /// 1位:表示正硬限位信号 +EL
//        /// 2位:表示负硬限位信号–EL
//        /// 3位:表示急停信号 EMG
//        /// 4位:表示原点信号 ORG
//        /// 5位:无
//        /// 6位:表示正软限位信号+SL
//        /// 7位:表示负软件限位信号-SL
//        /// </summary>
//        /// <returns></returns>
//        public uint GetIOStatus()
//        {
//            return LTDMC.dmc_axis_io_status(CardId, NoId);
//        }
//        /// <summary>
//        /// 是否有ALarm
//        /// </summary>
//        /// <returns></returns>
//        public bool IsAlarm()
//        {
//            uint data = LTDMC.dmc_axis_io_status(CardId, NoId);
//            var v = data & 1;
//            return v > 0;
//        }
//        /// <summary>
//        /// 正硬限位
//        /// </summary>
//        /// <returns></returns>
//        public bool IsELP()
//        {
//            uint data = LTDMC.dmc_axis_io_status(CardId, NoId);
//            var v = ((1 << 1) & data);
//            return v > 0;
//        }
//        /// <summary>
//        /// 负硬限位
//        /// </summary>
//        /// <returns></returns>
//        public bool IsELN()
//        {
//            uint data = LTDMC.dmc_axis_io_status(CardId, NoId);
//            var v = ((1 << 2) & data);
//            return v > 0;
//        }
//        /// <summary>
//        /// 急停信号
//        /// </summary>
//        /// <returns></returns>
//        public bool IsEMG()
//        {
//            uint data = LTDMC.dmc_axis_io_status(CardId, NoId);
//            var v = ((1 << 3) & data);
//            return v > 0;
//        }
//        /// <summary>
//        /// 原点信号
//        /// </summary>
//        /// <returns></returns>
//        public bool IsORG()
//        {
//            uint data = LTDMC.dmc_axis_io_status(CardId, NoId);
//            var v = ((1 << 4) & data);
//            return v > 0;
//        }
//        /// <summary>
//        /// 正软限位
//        /// </summary>
//        /// <returns></returns>
//        public bool IsSLP()
//        {
//            uint data = LTDMC.dmc_axis_io_status(CardId, NoId);
//            var v = ((1 << 6) & data);
//            return v > 0;
//        }
//        /// <summary>
//        /// 负软限位信号
//        /// </summary>
//        /// <returns></returns>
//        public bool IsSLN()
//        {
//            uint data = LTDMC.dmc_axis_io_status(CardId, NoId);
//            var v = ((1 << 7) & data);
//            return v > 0;
//        }
//        /// <summary>
//        /// 清除报警
//        /// </summary>
//        public void ClearAlarm()
//        {
//            IsMoveTimeoutError = false;
//            IsStatusError = false;
//            IsHomeError = false;
//            LTDMC.nmc_clear_axis_errcode(Electronic.CardId, NoId);
//        }

//    }
//}
